iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0

淺談一個關於標註的商業邏輯
今天一個圖片內有N個標註,需要將其轉為YOLO格式

  • image

    • width
    • height
    • depth
    • path
  • label

    • coordniates
    • image_path
    • tag

bussiness_logic.py


def fetch_and_format_labels():
    image = fetch_image_info()
    labels = fetch_labels_info()

label_formater.py

def yolo(image_width, image_height, labels_coordniate):
    # implement yolo logic

今天又有另外一個商業邏輯要將標注轉為PascalXML
所以程式必須改為
bussiness_logic.py


def fetch_and_format_labels():
    image = fetch_image_info()
    labels = fetch_labels_info()
    return [label_formater.yolo(image['width'], image['height'], label['coordniates']) for label in labels]

bussiness_logic1.py


def fetch_and_format_labels():
    image = fetch_image_info()
    labels = fetch_labels_info()
    return [label_formater.pascal(image['path'], image['width'], image['height'], image['depth'], label['coordniates']) for label in labels]

label_formater.py

def yolo(image_width, image_height, labels_coordniate):
    # implement yolo logic

def pascalXML(path, image_width, image_height, image_depth, labels_coordniate):
    # implement yolo logic

問題來了
今天如果又要支援其他格式,例如coco,開發商業邏輯的就需要知道coco應該傳哪些參數
今天如果bussiness_logic1要改成支援Yolo、是否還要改動參數呢?
如果要開發一個商業邏輯4,開發者還要去找到該傳哪些參數
也就是說商業邏輯跟formatter產生了依賴性
這邊其實同時違反了里氏替換原則跟控制反轉
更簡單的理解就是商業邏輯需要知道底層如何實作,儘管這顯然不是商業邏輯的責任

當然在動態語言如Python,我們可以簡單把東西全部丟到dict like


def fetch_and_format_labels():
    image = fetch_image_info()
    labels = fetch_labels_info()
    return [label_formater.pascal(image, label) for label in labels]

label_formater.py

def yolo(image, labelimage):
    # implement yolo logic

def pascalXML(image, label):
    # implement yolo logic

看起來沒問題了,對吧?
於是今天下一個改動是要支援Coco
coco formater的開發者要怎麼知道image, label有哪些參數呢?
他只能回去看bussiness實作來猜
這其實一樣違反依賴反轉,依賴反轉是需要雙方依賴於介面而非彼此
那問題來了 怎麼辦呢?
這時候就要請出DTO來
設兩個Dto:
dto.py

@dataclass
class Image:
    labels: List[Label]
    path = ''
    width = 0
    height = 0
    depth = 3

@dataclass
class Label:
    coordniates: List[List[float]] = field(default_factory=list
    tag = ''

此時

def yolo(image: Image):
    labels = image.labels
    # implement yolo logic

def pascalXML(image: Image):
   labels = image.labels
    # implement yolo logic

business logic只需要負責把image丟進formatter
而formatter只需要知道dto長什麼樣子,跟business logic到底怎麼拿到,如何組出來都跟formatter無關

在一個多人開發,持續維護的架構中,如果有一堆參數有一個明顯的歸屬class
而且這個class很多都module都需要用,就要考慮訂一個DTO來處理
可以減少很多溝通上的成本,也可以少寫很多文件


上一篇
D4 - Module的邊界
下一篇
D6 - 在開始實作之前,淺談那些關於文件的事情
系列文
寫個好的lib大家用吧!那些好用的lib常見的套路與想法25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言